/********************************************************************************/
/********************************************************************************/

#ifndef TPM2_STRUCTURE_H
#define TPM2_STRUCTURE_H

#include "string.h"
#include "sha1.h"
#include "sm3.h"
#include "sm3_ext.h"
#include "sm4.h"
#include "GpMacros.h"
#include "Memory_fp.h"
#include "TpmAlgorithmDefines.h"

enum dtype_tpm2_general
{
    TYPE(TPM2_INTERNAL) = 0x2101,
    TYPE(TPM2_EXTERNAL) = 0x2102,
    TYPE(TPM2_IN_CAP) = 0x2103,
    TYPE(TPM2_IN_KEY) = 0x2104,
    TYPE(TPM2_NV) = 0x2105,
    TYPE(TPM2_PCR) = 0x2106,
    TYPE(TPM2_AUTH) = 0x2107,
    TYPE(TPM2_KEY) = 0x2108,
    TYPE(TPM2_IDENTITY) = 0x2109,
    TYPE(TPM2_SEAL) = 0x210A,
    TYPE(TPM2_SENSITIVE) = 0x210B,
    TYPE(TPM2_PUBLIC) = 0x210C
};

enum subtype_tpm2_external
{
    SUBTYPE(TPM2_EXTERNAL, INPUT_COMMAND) = 0x01,
    SUBTYPE(TPM2_EXTERNAL, RETURN_DATA) = 0x02
};

enum subtype_tpm2_pcr_struct
{
    SUBTYPE(TPM2_PCR, TPMS_PCR_SELECTION) = 0x01,
    SUBTYPE(TPM2_PCR, TPML_PCR_SELECTION) = 0x02,
    SUBTYPE(TPM2_PCR, TPML_DIGEST) = 0x03
};

enum subtype_tpm2_key
{
    SUBTYPE(TPM2_KEY, TPM2B_NAME) = 0x01,
    SUBTYPE(TPM2_KEY, TPMS_SCHEME_HASH) = 0x02,
    SUBTYPE(TPM2_KEY, TPMS_SCHEME_HMAC) = 0x03,
    SUBTYPE(TPM2_KEY, TPMS_SCHEME_XOR) = 0x04,
    SUBTYPE(TPM2_KEY, TPMU_SCHEME_KEYEDHASH) = 0x05,
    SUBTYPE(TPM2_KEY, TPMT_KEYEDHASH_SCHEME) = 0x06,
    SUBTYPE(TPM2_KEY, TPMS_KEYEDHASH_PARMS) = 0x07,
    SUBTYPE(TPM2_KEY, TPMU_SYM_KEY_BITS) = 0x08,
    SUBTYPE(TPM2_KEY, TPMU_SYM_MODE) = 0x09,
    SUBTYPE(TPM2_KEY, TPMT_SYM_DEF_OBJECT) = 0x0A,
    SUBTYPE(TPM2_KEY, TPMS_SYMCIPHER_PARMS) = 0x0B,
    SUBTYPE(TPM2_KEY, TPMS_SCHEME_ECDAA) = 0x0C,
    SUBTYPE(TPM2_KEY, TPMU_ASYM_SCHEME) = 0x0D,
    SUBTYPE(TPM2_KEY, TPM2B_ECC_PARAMETER) = 0x0E,
    SUBTYPE(TPM2_KEY, TPMS_ECC_POINT) = 0x0F,
    SUBTYPE(TPM2_KEY, TPMT_ECC_SCHEME) = 0x10,
    SUBTYPE(TPM2_KEY, TPMU_KDF_SCHEME) = 0x11,
    SUBTYPE(TPM2_KEY, TPMT_KDF_SCHEME) = 0x12,
    SUBTYPE(TPM2_KEY, TPMS_ECC_PARMS) = 0x13,
    SUBTYPE(TPM2_KEY, TPMT_ASYM_SCHEME) = 0x14,
    SUBTYPE(TPM2_KEY, TPMS_ASYM_PARMS) = 0x15,
    SUBTYPE(TPM2_KEY, TPM2B_LABEL) = 0x16,
    SUBTYPE(TPM2_KEY, TPMS_DERIVE) = 0x17,
    SUBTYPE(TPM2_KEY, TPM2B) = 0x18,
    SUBTYPE(TPM2_KEY, TPM2B_DIGEST) = 0x19,
    SUBTYPE(TPM2_KEY, TPM2B_DATA) = 0x1A
};

enum subtype_tpm2_public
{
    SUBTYPE(TPM2_PUBLIC, TPMU_PUBLIC_PARMS) = 0x01,
    SUBTYPE(TPM2_PUBLIC, TPMU_PUBLIC_ID) = 0x02,
    SUBTYPE(TPM2_PUBLIC, TPMT_PUBLIC) = 0x03
};

enum subtype_tpm2_auth
{
    SUBTYPE(TPM2_AUTH, TPM2B_AUTH) = 0x01,
    SUBTYPE(TPM2_AUTH, TPM2B_PUBLIC) = 0x02,
    SUBTYPE(TPM2_AUTH, TPM2B_SENSITIVE_DATA) = 0x03,
    SUBTYPE(TPM2_AUTH, TPMS_SENSITIVE_CREATE) = 0x04,
    SUBTYPE(TPM2_AUTH, TPM2B_SENSITIVE_CREATE) = 0x05,
    SUBTYPE(TPM2_AUTH, TPMS_CREATION_DATA) = 0x06,
    SUBTYPE(TPM2_AUTH, TPM2B_CREATION_DATA) = 0x07,
    SUBTYPE(TPM2_AUTH, TPMT_TK_CREATION) = 0x08
};

typedef struct tpm2_external_input_command
{
    UINT16 tag;
    int commandSize;
    int commandCode;
} __attribute__((packed)) RECORD(TPM2_EXTERNAL, INPUT_COMMAND);

typedef struct tpm2_external_return_data
{
    UINT16 tag;
    int responseSize;
    int responseCode;
} __attribute__((packed)) RECORD(TPM2_EXTERNAL, RETURN_DATA);

typedef TPM2B RECORD(TPM2_KEY, TPM2B);
typedef TPM2B_DIGEST RECORD(TPM2_KEY, TPM2B_DIGEST);
typedef TPM2B_DATA RECORD(TPM2_KEY, TPM2B_DATA);

// Table 2:40
typedef struct TPMA_ACT
{
    unsigned signaled : 1;
    unsigned preserveSignaled : 1;
    unsigned Reserved_bits_at_2 : 30;
} __attribute__((packed)) TPMA_ACT;
// Table 2:86 - Definition of TPMS_PCR_SELECTION Structure
typedef struct tpms_pcr_selection
{
    UINT16 hash;
    BYTE sizeofSelect;
    BYTE *pcrSelect;
} __attribute__((packed)) RECORD(TPM2_PCR, TPMS_PCR_SELECTION);
typedef RECORD(TPM2_PCR, TPMS_PCR_SELECTION) TPMS_PCR_SELECTION;

// Table 2:104 - Definition of TPML_PCR_SELECTION Structure
typedef struct tpml_pcr_selection
{
    int count;
    TPMS_PCR_SELECTION *pcrSelections;
} __attribute__((packed)) RECORD(TPM2_PCR, TPML_PCR_SELECTION);
typedef RECORD(TPM2_PCR, TPML_PCR_SELECTION) TPML_PCR_SELECTION;

// Table 2:101 - Definition of TPML_DIGEST Structure
typedef struct tpml_digest
{
    UINT32 count;          // count {2:}  number of digests in the list, minimum is two. 列表中的摘要数量，最少为两个
    TPM2B_DIGEST *digests; // digests[count]{:8}   a list of digests. For TPM2_PolicyOR(), all digests will have been computed using the digest of the policy session. For TPM2_PCR_Read(), each digest will be the size of the digest for the bank containing the PCR.
} __attribute__((packed)) RECORD(TPM2_PCR, TPML_DIGEST);
typedef RECORD(TPM2_PCR, TPML_DIGEST) TPML_DIGEST;

/* Table 2:71 - Definition of TPMU_HA Union  */
typedef struct
{
    BYTE sm3_256[SM3_256_DIGEST_SIZE];
} __attribute__((packed)) TPMU_HA;
/* Table 2:72 - Definition of TPMT_HA Structure  */
typedef struct
{
    TPMI_ALG_HASH hashAlg;
    TPMU_HA digest;
} __attribute__((packed)) TPMT_HA;

// typedef struct tpm2b_auth
// {
//         UINT16 size;
//         BYTE *buffer;
// } __attribute__((packed)) RECORD(TPM2_AUTH, TPM2B_AUTH);
// typedef RECORD(TPM2_AUTH, TPM2B_AUTH) TPM2B_AUTH;

//  Table 2:74 - Definition of TPM2B_DATA Structure
// typedef struct tpm2b_data
// {
//         UINT16 size;
//         BYTE *buffer;
// } __attribute__((packed)) RECORD(TPM2_AUTH, TPM2B_DATA);
// typedef RECORD(TPM2_AUTH, TPM2B_DATA) TPM2B_DATA;

//  Table 2:75 - Definition of Types for TPM2B_NONCE
// typedef  TPM2B_DIGEST       TPM2B_NONCE;
//  Table 2:76 - Definition of Types for TPM2B_AUTH
// typedef  TPM2B_DIGEST       TPM2B_AUTH;
//  Table 2:77 - Definition of Types for TPM2B_OPERAND
// typedef  TPM2B_DIGEST       TPM2B_OPERAND;

/* Table 2:78 - Definition of TPM2B_EVENT Structure  */
typedef struct tpm2b_event
{
    TPM2B b;
} __attribute__((packed)) TPM2B_EVENT;

/* Table 2:79 - Definition of TPM2B_MAX_BUFFER Structure  */
typedef struct tpm2b_max_buffer
{
    TPM2B b;
} __attribute__((packed)) TPM2B_MAX_BUFFER;
/* Table 2:80 - Definition of TPM2B_MAX_NV_BUFFER Structure  */
typedef struct tpm2b_max_nv_buffer
{
    TPM2B b;
} __attribute__((packed)) TPM2B_MAX_NV_BUFFER;
/* Table 2:82 - Definition of TPM2B_TIMEOUT Structure */
typedef struct tpm2b_timeout
{
    TPM2B b;
} __attribute__((packed)) TPM2B_TIMEOUT;
/* Table 2:82 - Definition of TPM2B_IV Structure  */
typedef struct
{
    TPM2B b;
} __attribute__((packed)) TPM2B_IV;

//  Table 2:84 - Definition of TPM2B_NAME Structure
// typedef struct tpm2b_name
// {
//         UINT16 size;
//         BYTE *name;
// } __attribute__((packed)) RECORD(TPM2_KEY, TPM2B_NAME);
// typedef RECORD(TPM2_KEY, TPM2B_NAME) TPM2B_NAME;
typedef TPM2B_NAME RECORD(TPM2_KEY, TPM2B_NAME);

/* Table 2:89 - Definition of TPMT_TK_CREATION Structure  */
typedef struct tpmt_tk_creation
{
    //TODO  NOTE： tpm2_st_value 和 TPM_ST 定义在不同文件中， TPM_ST 为源码中定义； tpm2_st_value 为自定义，直接使用枚举enum tpm2_st_value 的值。
    TPM_ST tag;
    //TODO  NOTE： tpmi_rh_hierrchy 和 TPMI_RH_HIERARCHY 定义在不同文件中， TPMI_RH_HIERARCHY 为源码中定义； tpmi_rh_hierrchy 为自定义，直接使用枚举enum tpmi_rh_hierrchy 的值。
    TPMI_RH_HIERARCHY hierarchy;
    TPM2B_DIGEST digest;
} __attribute__((packed)) RECORD(TPM2_AUTH, TPMT_TK_CREATION);
typedef RECORD(TPM2_AUTH, TPMT_TK_CREATION) TPMT_TK_CREATION;
/* Table 2:90 - Definition of TPMT_TK_VERIFIED Structure  */
typedef struct
{
    TPM_ST tag;
    TPMI_RH_HIERARCHY hierarchy;
    TPM2B_DIGEST digest;
} __attribute__((packed)) TPMT_TK_VERIFIED;
/* Table 2:91 - Definition of TPMT_TK_AUTH Structure  */
typedef struct
{
    TPM_ST tag;
    TPMI_RH_HIERARCHY hierarchy;
    TPM2B_DIGEST digest;
} __attribute__((packed)) TPMT_TK_AUTH;
/* Table 2:92 - Definition of TPMT_TK_HASHCHECK Structure  */
typedef struct
{
    TPM_ST tag;
    TPMI_RH_HIERARCHY hierarchy;
    TPM2B_DIGEST digest;
} __attribute__((packed)) TPMT_TK_HASHCHECK;
/* Table 2:93 - Definition of TPMS_ALG_PROPERTY Structure  */
typedef struct
{
    TPM_ALG_ID alg;
    TPMA_ALGORITHM algProperties;
} __attribute__((packed)) TPMS_ALG_PROPERTY;
/* Table 2:94 - Definition of TPMS_TAGGED_PROPERTY Structure  */
typedef struct
{
    TPM_PT property;
    UINT32 value;
} __attribute__((packed)) TPMS_TAGGED_PROPERTY;
/* Table 2:95 - Definition of TPMS_TAGGED_PCR_SELECT Structure  */
typedef struct
{
    TPM_PT_PCR tag;
    BYTE sizeofSelect;
    BYTE *pcrSelect;
} __attribute__((packed)) TPMS_TAGGED_PCR_SELECT;
/* Table 2:96 - Definition of TPMS_TAGGED_POLICY Structure  */
typedef struct
{
    TPM_HANDLE handle;
    TPMT_HA policyHash;
} __attribute__((packed)) TPMS_TAGGED_POLICY;
/* Table 105 - Definition of TPMS_ACT_DATA Structure <OUT> */
typedef struct
{
    TPM_HANDLE handle;
    UINT32 timeout;
    TPMA_ACT attributes;
} __attribute__((packed)) TPMS_ACT_DATA;
/* Table 2:97 - Definition of TPML_CC Structure  */
typedef struct
{
    UINT32 count;
    TPM_CC commandCodes[MAX_CAP_CC];
} __attribute__((packed)) TPML_CC;
/* Table 2:98 - Definition of TPML_CCA Structure  */
typedef struct
{
    UINT32 count;
    TPMA_CC commandAttributes[MAX_CAP_CC];
} __attribute__((packed)) TPML_CCA;
/* Table 2:99 - Definition of TPML_ALG Structure  */
typedef struct
{
    UINT32 count;
    TPM_ALG_ID algorithms[MAX_ALG_LIST_SIZE];
} __attribute__((packed)) TPML_ALG;
/* Table 2:100 - Definition of TPML_HANDLE Structure  */
typedef struct
{
    UINT32 count;
    TPM_HANDLE handle[MAX_CAP_HANDLES];
} __attribute__((packed)) TPML_HANDLE;
/* Table 2:102 - Definition of TPML_DIGEST_VALUES Structure  */
typedef struct
{
    UINT32 count;
    TPMT_HA digests[HASH_COUNT];
} __attribute__((packed)) TPML_DIGEST_VALUES;
/* Table 2:105 - Definition of TPML_ALG_PROPERTY Structure  */
typedef struct
{
    UINT32 count;
    TPMS_ALG_PROPERTY algProperties[MAX_CAP_ALGS];
} __attribute__((packed)) TPML_ALG_PROPERTY;
/* Table 2:106 - Definition of TPML_TAGGED_TPM_PROPERTY Structure  */
typedef struct
{
    UINT32 count;
    TPMS_TAGGED_PROPERTY tpmProperty[MAX_TPM_PROPERTIES];
} __attribute__((packed)) TPML_TAGGED_TPM_PROPERTY;
/* Table 2:107 - Definition of TPML_TAGGED_PCR_PROPERTY Structure  */
typedef struct
{
    UINT32 count;
    TPMS_TAGGED_PCR_SELECT pcrProperty[MAX_PCR_PROPERTIES];
} __attribute__((packed)) TPML_TAGGED_PCR_PROPERTY;
/* Table 2:108 - Definition of TPML_ECC_CURVE Structure  */
typedef struct
{
    UINT32 count;
    TPM_ECC_CURVE eccCurves[MAX_ECC_CURVES];
} __attribute__((packed)) TPML_ECC_CURVE;
/* Table 2:109 - Definition of TPML_TAGGED_POLICY Structure  */
typedef struct
{
    UINT32 count;
    TPMS_TAGGED_POLICY policies[MAX_TAGGED_POLICIES];
} __attribute__((packed)) TPML_TAGGED_POLICY;
/* Table 2:118 - Definition of TPML_ACT_DATA Structure <OUT> */
typedef struct
{
    UINT32 count;
    TPMS_ACT_DATA actData[MAX_ACT_DATA];
} __attribute__((packed)) TPML_ACT_DATA;
/* Table 2:110 - Definition of TPMU_CAPABILITIES Union  */
typedef union
{
    TPML_ALG_PROPERTY algorithms;
    TPML_HANDLE handles;
    TPML_CCA command;
    TPML_CC ppCommands;
    TPML_CC auditCommands;
    TPML_PCR_SELECTION assignedPCR;
    TPML_TAGGED_TPM_PROPERTY tpmProperties;
    TPML_TAGGED_PCR_PROPERTY pcrProperties;
#if ALG_ECC
    TPML_ECC_CURVE eccCurves;
#endif // ALG_ECC
    TPML_TAGGED_POLICY authPolicies;
    TPML_ACT_DATA actData;
} __attribute__((packed)) TPMU_CAPABILITIES;
/* Table 2:111 - Definition of TPMS_CAPABILITY_DATA Structure  */
typedef struct
{
    TPM_CAP capability;
    TPMU_CAPABILITIES data;
} __attribute__((packed)) TPMS_CAPABILITY_DATA;
/* Table 2:112 - Definition of TPMS_CLOCK_INFO Structure  */
typedef struct
{
    UINT64 clock;
    UINT32 resetCount;
    UINT32 restartCount;
    TPMI_YES_NO safe;
} __attribute__((packed)) TPMS_CLOCK_INFO;
/* Table 2:113 - Definition of TPMS_TIME_INFO Structure  */
typedef struct
{
    UINT64 time;
    TPMS_CLOCK_INFO clockInfo;
} __attribute__((packed)) TPMS_TIME_INFO;
/* Table 2:114 - Definition of TPMS_TIME_ATTEST_INFO Structure  */
typedef struct
{
    TPMS_TIME_INFO time;
    UINT64 firmwareVersion;
} __attribute__((packed)) TPMS_TIME_ATTEST_INFO;
/* Table 2:115 - Definition of TPMS_CERTIFY_INFO Structure  */
typedef struct
{
    TPM2B_NAME name;
    TPM2B_NAME qualifiedName;
} __attribute__((packed)) TPMS_CERTIFY_INFO;
/* Table 2:116 - Definition of TPMS_QUOTE_INFO Structure  */
typedef struct
{
    TPML_PCR_SELECTION pcrSelect;
    TPM2B_DIGEST pcrDigest;
} __attribute__((packed)) TPMS_QUOTE_INFO;
/* Table 2:117 - Definition of TPMS_COMMAND_AUDIT_INFO Structure  */
typedef struct
{
    UINT64 auditCounter;
    TPM_ALG_ID digestAlg;
    TPM2B_DIGEST auditDigest;
    TPM2B_DIGEST commandDigest;
} __attribute__((packed)) TPMS_COMMAND_AUDIT_INFO;
/* Table 2:118 - Definition of TPMS_SESSION_AUDIT_INFO Structure  */
typedef struct
{
    TPMI_YES_NO exclusiveSession;
    TPM2B_DIGEST sessionDigest;
} __attribute__((packed)) TPMS_SESSION_AUDIT_INFO;
/* Table 2:119 - Definition of TPMS_CREATION_INFO Structure  */
typedef struct
{
    TPM2B_NAME objectName;
    TPM2B_DIGEST creationHash;
} __attribute__((packed)) TPMS_CREATION_INFO;
/* Table 2:120 - Definition of TPMS_NV_CERTIFY_INFO Structure  */
typedef struct
{
    TPM2B_NAME indexName;
    UINT16 offset;
    TPM2B_MAX_NV_BUFFER nvContents;
} __attribute__((packed)) TPMS_NV_CERTIFY_INFO;
/* Table 125 - Definition of TPMS_NV_DIGEST_CERTIFY_INFO Structure <OUT> */
typedef struct
{
    TPM2B_NAME indexName;
    TPM2B_DIGEST nvDigest;
} __attribute__((packed)) TPMS_NV_DIGEST_CERTIFY_INFO;
/* Table 2:121 - Definition of TPMI_ST_ATTEST Type  */
typedef TPM_ST TPMI_ST_ATTEST;
/* Table 2:122 - Definition of TPMU_ATTEST Union  */
typedef union
{
    TPMS_CERTIFY_INFO certify;
    TPMS_CREATION_INFO creation;
    TPMS_QUOTE_INFO quote;
    TPMS_COMMAND_AUDIT_INFO commandAudit;
    TPMS_SESSION_AUDIT_INFO sessionAudit;
    TPMS_TIME_ATTEST_INFO time;
    TPMS_NV_CERTIFY_INFO nv;
    TPMS_NV_DIGEST_CERTIFY_INFO nvDigest;
} __attribute__((packed)) TPMU_ATTEST;
/* Table 2:123 - Definition of TPMS_ATTEST Structure  */
typedef struct
{
    TPM_GENERATED magic;
    TPMI_ST_ATTEST type;
    TPM2B_NAME qualifiedSigner;
    TPM2B_DATA extraData;
    TPMS_CLOCK_INFO clockInfo;
    UINT64 firmwareVersion;
    TPMU_ATTEST attested;
} __attribute__((packed)) TPMS_ATTEST;
/* Table 2:124 - Definition of TPM2B_ATTEST Structure  */
typedef union
{
    struct
    {
        UINT16 size;
        BYTE attestationData[sizeof(TPMS_ATTEST)];
    } t;
    TPM2B b;
} __attribute__((packed)) TPM2B_ATTEST;
/* Table 2:125 - Definition of TPMS_AUTH_COMMAND Structure  */
typedef struct
{
    TPMI_SH_AUTH_SESSION sessionHandle;
    TPM2B_NONCE nonce;
    TPMA_SESSION sessionAttributes;
    TPM2B_AUTH hmac;
} __attribute__((packed)) TPMS_AUTH_COMMAND;
/* Table 2:126 - Definition of TPMS_AUTH_RESPONSE Structure  */
typedef struct
{
    TPM2B_NONCE nonce;
    TPMA_SESSION sessionAttributes;
    TPM2B_AUTH hmac;
} __attribute__((packed)) TPMS_AUTH_RESPONSE;
/* Table 2:127 - Definition of TPMI_TDES_KEY_BITS Type  */
typedef TPM_KEY_BITS TPMI_TDES_KEY_BITS;
/* Table 2:127 - Definition of TPMI_AES_KEY_BITS Type  */
typedef TPM_KEY_BITS TPMI_AES_KEY_BITS;
/* Table 2:127 - Definition of TPMI_SM4_KEY_BITS Type  */
typedef TPM_KEY_BITS TPMI_SM4_KEY_BITS;
/* Table 2:127 - Definition of TPMI_CAMELLIA_KEY_BITS Type  */
typedef TPM_KEY_BITS TPMI_CAMELLIA_KEY_BITS;
// Table 2:128 - Definition of TPMU_SYM_KEY_BITS Union
// 此联合用于收集对称加密密钥大小。
typedef struct tpmu_sym_key_bits
{
    TPMI_TDES_KEY_BITS tdes;
    TPMI_AES_KEY_BITS aes;
    TPMI_SM4_KEY_BITS sm4;
    TPM_KEY_BITS sym;   // 参考代码使用该条目以独立于对称算法的方式引用密钥位字段
    TPMI_ALG_HASH xorr; // xor项是哈希算法选择器，而不是以位为单位的密钥大小。xor条目仅在用于选择参数加密值的TPMT_SYM_DEF中选择。
} __attribute__((packed)) RECORD(TPM2_KEY, TPMU_SYM_KEY_BITS);
typedef RECORD(TPM2_KEY, TPMU_SYM_KEY_BITS) TPMU_SYM_KEY_BITS;

// Table 2:129 - Definition of TPMU_SYM_MODE Union
typedef struct tpmu_sym_mode
{
    TPMI_ALG_SYM_MODE sm4;
    TPMI_ALG_SYM_MODE sym;
} __attribute__((packed)) RECORD(TPM2_KEY, TPMU_SYM_MODE);
typedef RECORD(TPM2_KEY, TPMU_SYM_MODE) TPMU_SYM_MODE;

// Table 2:131 - Definition of TPMT_SYM_DEF Structure
typedef struct
{
    TPMI_ALG_SYM algorithm;
    TPMU_SYM_KEY_BITS keyBits;
    TPMU_SYM_MODE mode;
} __attribute__((packed)) TPMT_SYM_DEF;

// Table 2:132 - Definition of TPMT_SYM_DEF_OBJECT Structure
typedef struct tpmt_sym_def_object
{
    TPMI_ALG_SYM_OBJECT algorithm; // 选择对称分组密码。  当在父对象的参数区域中使用时，这应该是受支持的分组密码，而不是TPM_ALG_NULL
    TPMU_SYM_KEY_BITS keyBits;     // 秘钥大小。
    TPMU_SYM_MODE mode;            // 默认模式。 在父对象的参数区域中使用时，应为TPM_ALG_CFB。
} __attribute__((packed)) RECORD(TPM2_KEY, TPMT_SYM_DEF_OBJECT);
typedef RECORD(TPM2_KEY, TPMT_SYM_DEF_OBJECT) TPMT_SYM_DEF_OBJECT;
/* Table 2:133 - Definition of TPM2B_SYM_KEY Structure  */
typedef struct
{
    TPM2B b;
} __attribute__((packed)) TPM2B_SYM_KEY;
/* Table 2:134 - Definition of TPMS_SYMCIPHER_PARMS Structure  */
typedef struct tpms_symcipher_parms
{
    TPMT_SYM_DEF_OBJECT sym;
} __attribute__((packed)) RECORD(TPM2_KEY, TPMS_SYMCIPHER_PARMS);
typedef RECORD(TPM2_KEY, TPMS_SYMCIPHER_PARMS) TPMS_SYMCIPHER_PARMS;

// Table 2:136 - Definition of TPMS_DERIVE Structure
//This structure contains the label and context fields for a derived object. These values are used in the derivation KDF. The values in the unique field of inPublic area template take precedence over the values in the inSensitive parameter.
typedef struct tpms_derive
{
    TPM2B_LABEL label;
    TPM2B_LABEL context;
} __attribute__((packed)) RECORD(TPM2_KEY, TPMS_DERIVE);
typedef RECORD(TPM2_KEY, TPMS_DERIVE) TPMS_DERIVE;

//  Table 2:139 - Definition of TPM2B_SENSITIVE_DATA Structure
// typedef struct tpm2b_sensitive_data
// {
//         UINT16 size;
//         BYTE *buffer;
// } __attribute__((packed)) RECORD(TPM2_AUTH, TPM2B_SENSITIVE_DATA);
// typedef RECORD(TPM2_AUTH, TPM2B_SENSITIVE_DATA) TPM2B_SENSITIVE_DATA;
typedef TPM2B_SENSITIVE_DATA RECORD(TPM2_AUTH, TPM2B_SENSITIVE_DATA);

//  Table 2:140 - Definition of TPMS_SENSITIVE_CREATE Structure
typedef struct tpms_sensitive_create
{
    // 查看TCG_TPM2_Part1 27.3.2 : userAuth .
    TPM2B_AUTH userAuth;
    // 查看TCG_TPM2_Part1 27.3.3 : data .
    TPM2B_SENSITIVE_DATA data;
} __attribute__((packed)) RECORD(TPM2_AUTH, TPMS_SENSITIVE_CREATE);
typedef RECORD(TPM2_AUTH, TPMS_SENSITIVE_CREATE) TPMS_SENSITIVE_CREATE;
//  Table 2:141 - Definition of TPM2B_SENSITIVE_CREATE Structure
typedef struct tpm2b_sensitive_create
{
    UINT16 size;
    TPMS_SENSITIVE_CREATE sensitive;
} __attribute__((packed)) RECORD(TPM2_AUTH, TPM2B_SENSITIVE_CREATE);
typedef RECORD(TPM2_AUTH, TPM2B_SENSITIVE_CREATE) TPM2B_SENSITIVE_CREATE;

// Table 2:142 - Definition of TPMS_SCHEME_HASH Structure
typedef struct tpms_scheme_hash
{
    TPMI_ALG_HASH hashAlg;
} __attribute__((packed)) RECORD(TPM2_KEY, TPMS_SCHEME_HASH);
typedef RECORD(TPM2_KEY, TPMS_SCHEME_HASH) TPMS_SCHEME_HASH;
// Table 2:143 - Definition of TPMS_SCHEME_ECDAA Structure
typedef struct tpms_scheme_ecdaa
{
    TPMI_ALG_HASH hashAlg;
    UINT16 count;
} __attribute__((packed)) RECORD(TPM2_KEY, TPMS_SCHEME_ECDAA);
typedef RECORD(TPM2_KEY, TPMS_SCHEME_ECDAA) TPMS_SCHEME_ECDAA;
/* Table 2:144 - Definition of TPMI_ALG_KEYEDHASH_SCHEME Type  */
typedef TPM_ALG_ID TPMI_ALG_KEYEDHASH_SCHEME;
/* Table 2:145 - Definition of Types for HMAC_SIG_SCHEME */
typedef TPMS_SCHEME_HASH TPMS_SCHEME_HMAC;
/* Table 2:146 - Definition of TPMS_SCHEME_XOR Structure  */
typedef struct tpms_scheme_xor
{
    TPMI_ALG_HASH hashAlg;
    TPMI_ALG_KDF kdf;
} __attribute__((packed)) RECORD(TPM2_KEY, TPMS_SCHEME_XOR);
typedef RECORD(TPM2_KEY, TPMS_SCHEME_XOR) TPMS_SCHEME_XOR;
/* Table 2:147 - Definition of TPMU_SCHEME_KEYEDHASH Union  */
typedef struct tpmu_scheme_keyedhash
{
#if ALG_HMAC
    TPMS_SCHEME_HMAC hmac;
#endif // ALG_HMAC
#if ALG_XOR
    TPMS_SCHEME_XOR xorr;
#endif // ALG_XOR
} __attribute__((packed)) RECORD(TPM2_KEY, TPMU_SCHEME_KEYEDHASH);
typedef RECORD(TPM2_KEY, TPMU_SCHEME_KEYEDHASH) TPMU_SCHEME_KEYEDHASH;
/* Table 2:148 - Definition of TPMT_KEYEDHASH_SCHEME Structure  */
typedef struct tpmt_keyedhash_scheme
{
    TPMI_ALG_KEYEDHASH_SCHEME scheme;
    TPMU_SCHEME_KEYEDHASH details;
} __attribute__((packed)) RECORD(TPM2_KEY, TPMT_KEYEDHASH_SCHEME);
typedef RECORD(TPM2_KEY, TPMT_KEYEDHASH_SCHEME) TPMT_KEYEDHASH_SCHEME;
// Table 2:149 - Definition of Types for RSA Signature Schemes
typedef TPMS_SCHEME_HASH TPMS_SIG_SCHEME_RSASSA;
typedef TPMS_SCHEME_HASH TPMS_SIG_SCHEME_RSAPSS;
// Table 2:150 - Definition of Types for ECC Signature Schemes
typedef TPMS_SCHEME_HASH TPMS_SIG_SCHEME_ECDSA;
typedef TPMS_SCHEME_HASH TPMS_SIG_SCHEME_SM2;
typedef TPMS_SCHEME_HASH TPMS_SIG_SCHEME_ECSCHNORR;
typedef TPMS_SCHEME_ECDAA TPMS_SIG_SCHEME_ECDAA;
/* Table 2:153 - Definition of Types for Encryption Schemes */
typedef TPMS_SCHEME_HASH TPMS_ENC_SCHEME_OAEP;
typedef TPMS_EMPTY TPMS_ENC_SCHEME_RSAES;
/* Table 2:154 - Definition of Types for ECC Key Exchange */
typedef TPMS_SCHEME_HASH TPMS_KEY_SCHEME_ECDH;
typedef TPMS_SCHEME_HASH TPMS_KEY_SCHEME_ECMQV;
/* Table 2:155 - Definition of Types for KDF Schemes */
typedef TPMS_SCHEME_HASH TPMS_SCHEME_MGF1;
typedef TPMS_SCHEME_HASH TPMS_SCHEME_KDF1_SP800_56A;
typedef TPMS_SCHEME_HASH TPMS_SCHEME_KDF2;
typedef TPMS_SCHEME_HASH TPMS_SCHEME_KDF1_SP800_108;
typedef TPMS_SCHEME_HASH TPMS_SCHEME_KDF2;
/* Table 2:156 - Definition of TPMU_KDF_SCHEME Union  */
typedef struct tpmu_kdf_scheme
{
    TPMS_SCHEME_KDF2 kdf2;
} __attribute__((packed)) RECORD(TPM2_KEY, TPMU_KDF_SCHEME);
typedef RECORD(TPM2_KEY, TPMU_KDF_SCHEME) TPMU_KDF_SCHEME;

// Table 2:157 - Definition of TPMT_KDF_SCHEME Structure
typedef struct tpmt_kdf_scheme
{
    TPMI_ALG_KDF scheme;
    TPMU_KDF_SCHEME details;
} __attribute__((packed)) RECORD(TPM2_KEY, TPMT_KDF_SCHEME);
typedef RECORD(TPM2_KEY, TPMT_KDF_SCHEME) TPMT_KDF_SCHEME;

// Table 2:159 - Definition of TPMU_ASYM_SCHEME Union
typedef struct tpmu_asym_scheme
{
    TPMS_SIG_SCHEME_ECDAA ecdaa;
    TPMS_SIG_SCHEME_SM2 sm2;
    TPMS_SCHEME_HASH anySig;
} __attribute__((packed)) RECORD(TPM2_KEY, TPMU_ASYM_SCHEME);
typedef RECORD(TPM2_KEY, TPMU_ASYM_SCHEME) TPMU_ASYM_SCHEME;

// Table 2:160 - Definition of TPMT_ASYM_SCHEME Structure
typedef struct tpmt_asym_scheme
{
    TPMI_ALG_ASYM_SCHEME scheme; // 任何非对称算法的所有方案类型的列表。
    TPMU_ASYM_SCHEME details;
} __attribute__((packed)) RECORD(TPM2_KEY, TPMT_ASYM_SCHEME);
typedef RECORD(TPM2_KEY, TPMT_ASYM_SCHEME) TPMT_ASYM_SCHEME;

// Table 2:169 - Definition of TPMS_ECC_POINT Structure
typedef struct tpms_ecc_point
{
    TPM2B_ECC_PARAMETER x;
    TPM2B_ECC_PARAMETER y;
} __attribute__((packed)) RECORD(TPM2_KEY, TPMS_ECC_POINT);
typedef RECORD(TPM2_KEY, TPMS_ECC_POINT) TPMS_ECC_POINT;
/* Table 2:170 - Definition of TPM2B_ECC_POINT Structure  */
typedef struct 
{
    UINT16 size;
    TPMS_ECC_POINT point;
} __attribute__((packed)) TPM2B_ECC_POINT;
// Table 2:173 - Definition of TPMT_ECC_SCHEME Structure
typedef struct tpmt_ecc_scheme
{
    TPMI_ALG_ECC_SCHEME scheme;
    TPMU_ASYM_SCHEME details;
} __attribute__((packed)) RECORD(TPM2_KEY, TPMT_ECC_SCHEME);
typedef RECORD(TPM2_KEY, TPMT_ECC_SCHEME) TPMT_ECC_SCHEME;
/* Table 2:174 - Definition of TPMS_ALGORITHM_DETAIL_ECC Structure  */
typedef struct
{
    TPM_ECC_CURVE curveID;
    UINT16 keySize;
    TPMT_KDF_SCHEME kdf;
    TPMT_ECC_SCHEME sign;
    TPM2B_ECC_PARAMETER p;
    TPM2B_ECC_PARAMETER a;
    TPM2B_ECC_PARAMETER b;
    TPM2B_ECC_PARAMETER gX;
    TPM2B_ECC_PARAMETER gY;
    TPM2B_ECC_PARAMETER n;
    TPM2B_ECC_PARAMETER h;
} __attribute__((packed)) TPMS_ALGORITHM_DETAIL_ECC;

/* Table 2:177 - Definition of TPMS_SIGNATURE_ECC Structure  */
typedef struct
{
    TPMI_ALG_HASH hash;
    TPM2B_ECC_PARAMETER signatureR;
    TPM2B_ECC_PARAMETER signatureS;
} __attribute__((packed)) TPMS_SIGNATURE_ECC;
/* Table 2:178 - Definition of Types for TPMS_SIGNATURE_ECC */
typedef TPMS_SIGNATURE_ECC TPMS_SIGNATURE_ECDAA;
typedef TPMS_SIGNATURE_ECC TPMS_SIGNATURE_ECDSA;
typedef TPMS_SIGNATURE_ECC TPMS_SIGNATURE_SM2;
typedef TPMS_SIGNATURE_ECC TPMS_SIGNATURE_ECSCHNORR;
/* Table 2:179 - Definition of TPMU_SIGNATURE Union  */
typedef union
{
#if ALG_ECC
    TPMS_SIGNATURE_ECDAA ecdaa;
#endif // ALG_ECC
#if ALG_RSA
    TPMS_SIGNATURE_RSASSA rsassa;
#endif // ALG_RSA
#if ALG_RSA
    TPMS_SIGNATURE_RSAPSS rsapss;
#endif // ALG_RSA
#if ALG_ECC
    TPMS_SIGNATURE_ECDSA ecdsa;
#endif // ALG_ECC
#if ALG_ECC
    TPMS_SIGNATURE_SM2 sm2;
#endif // ALG_ECC
#if ALG_ECC
    TPMS_SIGNATURE_ECSCHNORR ecschnorr;
#endif // ALG_ECC
#if ALG_HMAC
    TPMT_HA hmac;
#endif // ALG_HMAC
    TPMS_SCHEME_HASH any;
} __attribute__((packed)) TPMU_SIGNATURE;
/* Table 2:180 - Definition of TPMT_SIGNATURE Structure  */
typedef struct
{
    TPMI_ALG_SIG_SCHEME sigAlg;
    TPMU_SIGNATURE signature;
} __attribute__((packed)) TPMT_SIGNATURE;
/* Table 2:181 - Definition of TPMU_ENCRYPTED_SECRET Union  */
typedef union
{
#if ALG_ECC
    BYTE ecc[sizeof(TPMS_ECC_POINT)];
#endif // ALG_ECC
// #if 	ALG_RSA
//     BYTE                    rsa[MAX_RSA_KEY_BYTES];
// #endif   // ALG_RSA
#if ALG_SYMCIPHER
    BYTE symmetric[sizeof(TPM2B_DIGEST)];
#endif // ALG_SYMCIPHER
#if ALG_KEYEDHASH
    BYTE keyedHash[sizeof(TPM2B_DIGEST)];
#endif // ALG_KEYEDHASH
} __attribute__((packed)) TPMU_ENCRYPTED_SECRET;
/* Table 2:182 - Definition of TPM2B_ENCRYPTED_SECRET Structure  */
typedef struct tpm2b_encrypted_secret
{
    TPM2B b;
} __attribute__((packed)) TPM2B_ENCRYPTED_SECRET;
/* Table 2:184 - Definition of TPMU_PUBLIC_ID Union  */
typedef struct tpmu_public_id
{
#if ALG_KEYEDHASH
    TPM2B_DIGEST keyedHash;
#endif // ALG_KEYEDHASH
#if ALG_SYMCIPHER
    TPM2B_DIGEST sym;
#endif // ALG_SYMCIPHER
#if ALG_RSA
    TPM2B_PUBLIC_KEY_RSA rsa;
#endif // ALG_RSA
#if ALG_ECC
    TPMS_ECC_POINT ecc;
#endif                  // ALG_ECC
    TPMS_DERIVE derive; // 只有当parentHandle是一个派生父类时，TPM2_CreateLoaded才允许。
} __attribute__((packed)) RECORD(TPM2_PUBLIC, TPMU_PUBLIC_ID);
typedef RECORD(TPM2_PUBLIC, TPMU_PUBLIC_ID) TPMU_PUBLIC_ID;
/* Table 2:185 - Definition of TPMS_KEYEDHASH_PARMS Structure  */
typedef struct tpms_keyedhash_parms
{
    TPMT_KEYEDHASH_SCHEME scheme;
} __attribute__((packed)) RECORD(TPM2_KEY, TPMS_KEYEDHASH_PARMS);
typedef RECORD(TPM2_KEY, TPMS_KEYEDHASH_PARMS) TPMS_KEYEDHASH_PARMS;
// Table 2:186 - Definition of TPMS_ASYM_PARMS Structure
typedef struct tpms_asym_parms
{
    TPMT_SYM_DEF_OBJECT symmetric;
    TPMT_ASYM_SCHEME scheme;
} __attribute__((packed)) RECORD(TPM2_KEY, TPMS_ASYM_PARMS);
typedef RECORD(TPM2_KEY, TPMS_ASYM_PARMS) TPMS_ASYM_PARMS;

//  Table 2:188 - Definition of TPMS_ECC_PARMS Structure
//     该结构包含素模ECC的参数。
typedef struct tpms_ecc_parms
{
    TPMT_SYM_DEF_OBJECT symmetric; //对于限制性解密密钥，应设置为支持的对称算法、密钥大小和模式。 如果密钥不是受限解密密钥，则该字段应设置为TPM_ALG_NULL。

    // 如果设置了密钥的sign属性，则该密钥应为有效的签名方案。注：如果curveID中的符号参数表示强制方案，则此字段应具有相同的值。
    // 如果设置了密钥的decrypt属性，则该属性应为有效的密钥交换方案或TPM_ALG_NULL。
    // 如果密钥是存储密钥，则此字段应为TPM_ALG_NULL。
    TPMT_ECC_SCHEME scheme;
    TPMI_ECC_CURVE curveID; // ECC curve ID

    // 从Z值生成对称密钥的可选密钥派生方案.
    // 如果与curveID关联的kdf参数不是TPM_ALG_NULL，则需要为NULL。注意：目前没有此参数有效的命令，在参考代码中，此字段需要设置为TPM_ALG_NULL。
    TPMT_KDF_SCHEME kdf;
} __attribute__((packed)) RECORD(TPM2_KEY, TPMS_ECC_PARMS);
typedef RECORD(TPM2_KEY, TPMS_ECC_PARMS) TPMS_ECC_PARMS;

// Table 2:189 - Definition of TPMU_PUBLIC_PARMS Union
//     表198 — Definition of TPMU_PUBLIC_PARMS Union :定义了可能包含在密钥的公共部分中的参数定义结构。
//     如果对象可以是父对象，则第一个字段必须是TPMT_SYM_DEF_OBJECT。见11.1.7。
//     “+”表示可以同时设置两个，但应设置一个。“|” 指示可选设置。
typedef struct tpmu_public_parms
{
#if ALG_KEYEDHASH
    TPMS_KEYEDHASH_PARMS keyedHashDetail; // sign | decrypt | neither
#endif                                    // ALG_KEYEDHASH
#if ALG_SYMCIPHER
    TPMS_SYMCIPHER_PARMS symDetail; // sign | decrypt | neither
#endif                              // ALG_SYMCIPHER
#if ALG_RSA
    TPMS_RSA_PARMS rsaDetail; // decrypt + signs
#endif                        // ALG_RSA
#if ALG_ECC
    TPMS_ECC_PARMS eccDetail;                                     // decrypt + sign
#endif                                                            // ALG_ECC
    TPMS_ASYM_PARMS asymDetail;                                   // RSA和ECC密钥的通用方案结构
} __attribute__((packed)) RECORD(TPM2_PUBLIC, TPMU_PUBLIC_PARMS); //查看 part2 12.2.3.7  TPMU_PUBLIC_PARMS
typedef RECORD(TPM2_PUBLIC, TPMU_PUBLIC_PARMS) TPMU_PUBLIC_PARMS;
// Table 2:190 - Definition of TPMT_PUBLIC_PARMS Structure
typedef struct
{
    TPMI_ALG_PUBLIC type;
    TPMU_PUBLIC_PARMS parameters;
} __attribute__((packed)) TPMT_PUBLIC_PARMS;

#if USE_BIT_FIELD_STRUCTURES
/* This is the initializer for a TPMA_OBJECT structure. */
typedef struct tpma_object
{ // Table 2:31
    unsigned int Reserved_bit_at_0 : 1;
    unsigned int fixedTPM : 1;
    unsigned int stClear : 1;
    unsigned int Reserved_bit_at_3 : 1;
    unsigned int fixedParent : 1;
    unsigned int sensitiveDataOrigin : 1;
    unsigned int userWithAuth : 1;
    unsigned int adminWithPolicy : 1;
    unsigned int Reserved_bits_at_8 : 2;
    unsigned int noDA : 1;
    unsigned int encryptedDuplication : 1;
    unsigned int Reserved_bits_at_12 : 4;
    unsigned int restricted : 1;
    unsigned int decrypt : 1;
    unsigned int sign : 1;
    unsigned int x509sign : 1;
    unsigned int Reserved_bits_at_20 : 12;
} __attribute__((packed)) RECORD(TPM2_PUBLIC, TPMA_OBJECT);
typedef RECORD(TPM2_PUBLIC, TPMA_OBJECT) TPMA_OBJECT;
// This is the initializer for a TPMA_OBJECT structure
#define TPMA_OBJECT_INITIALIZER(					\
				bit_at_0,             fixedtpm,             stclear, \
				bit_at_3,             fixedparent,          sensitivedataorigin, \
				userwithauth,         adminwithpolicy,      bits_at_8, \
				noda,                 encryptedduplication, bits_at_12, \
				restricted,           decrypt,              sign, \
				x509sign,             bits_at_20)	\
	   {bit_at_0,             fixedtpm,             stclear,		\
	    bit_at_3,             fixedparent,          sensitivedataorigin, \
	    userwithauth,         adminwithpolicy,      bits_at_8,	\
	    noda,                 encryptedduplication, bits_at_12,	\
	    restricted,           decrypt,              sign,		\
	    x509sign,             bits_at_20}
#else // USE_BIT_FIELD_STRUCTURES
// This implements Table 2:31 TPMA_OBJECT using bit masking
typedef UINT32                              TPMA_OBJECT;
// #define TYPE_OF_TPMA_OBJECT                 UINT32
// #define TPMA_OBJECT_Reserved_bit_at_0       ((TPMA_OBJECT)1 << 0)
// #define TPMA_OBJECT_fixedTPM                ((TPMA_OBJECT)1 << 1)
// #define TPMA_OBJECT_stClear                 ((TPMA_OBJECT)1 << 2)
// #define TPMA_OBJECT_fixedParent             ((TPMA_OBJECT)1 << 4)
// #define TPMA_OBJECT_sensitiveDataOrigin     ((TPMA_OBJECT)1 << 5)
// #define TPMA_OBJECT_userWithAuth            ((TPMA_OBJECT)1 << 6)
// #define TPMA_OBJECT_adminWithPolicy         ((TPMA_OBJECT)1 << 7)
// #define TPMA_OBJECT_noDA                    ((TPMA_OBJECT)1 << 10)
// #define TPMA_OBJECT_encryptedDuplication    ((TPMA_OBJECT)1 << 11)
// #define TPMA_OBJECT_restricted              ((TPMA_OBJECT)1 << 16)
// #define TPMA_OBJECT_decrypt                 ((TPMA_OBJECT)1 << 17)
// #define TPMA_OBJECT_sign                    ((TPMA_OBJECT)1 << 18)
// #define TPMA_OBJECT_x509sign                ((TPMA_OBJECT)1 << 19)
// #define TPMA_OBJECT_reserved		    ((TPMA_OBJECT)0xfff0f309)
#define TYPE_OF_TPMA_OBJECT                 ((TPMA_OBJECT)0x00000000)
#define TPMA_OBJECT_Reserved_bit_at_0       ((TPMA_OBJECT)0x00000001)
#define TPMA_OBJECT_fixedTPM                ((TPMA_OBJECT)0x00000002)
#define TPMA_OBJECT_stClear                 ((TPMA_OBJECT)0x00000004)
#define TPMA_OBJECT_fixedParent             ((TPMA_OBJECT)0x00000010)
#define TPMA_OBJECT_sensitiveDataOrigin     ((TPMA_OBJECT)0x00000020)
#define TPMA_OBJECT_userWithAuth            ((TPMA_OBJECT)0x00000040)
#define TPMA_OBJECT_adminWithPolicy         ((TPMA_OBJECT)0x00000080)
#define TPMA_OBJECT_noDA                    ((TPMA_OBJECT)0x00000400)
#define TPMA_OBJECT_encryptedDuplication    ((TPMA_OBJECT)0x00000800)
#define TPMA_OBJECT_restricted              ((TPMA_OBJECT)0x00010000)
#define TPMA_OBJECT_decrypt                 ((TPMA_OBJECT)0x00020000)
#define TPMA_OBJECT_sign                    ((TPMA_OBJECT)0x00040000)
#define TPMA_OBJECT_x509sign                ((TPMA_OBJECT)0x00080000)
#define TPMA_OBJECT_reserved		    ((TPMA_OBJECT)0xfff0f309)
//  This is the initializer for a TPMA_OBJECT bit array.
#define TPMA_OBJECT_INITIALIZER(                                                   \
             bit_at_0,             fixedtpm,             stclear,                  \
             bit_at_3,             fixedparent,          sensitivedataorigin,      \
             userwithauth,         adminwithpolicy,      bits_at_8,                \
             noda,                 encryptedduplication, bits_at_12,               \
             restricted,           decrypt,              sign,                     \
             x509sign,             bits_at_20)                                     \
            {(fixedtpm << 1)              + (stclear << 2)               +         \
             (fixedparent << 4)           + (sensitivedataorigin << 5)   +         \
             (userwithauth << 6)          + (adminwithpolicy << 7)       +         \
             (noda << 10)                 + (encryptedduplication << 11) +         \
             (restricted << 16)           + (decrypt << 17)              +         \
             (sign << 18)                 + (x509sign << 19)}
#endif // USE_BIT_FIELD_STRUCTURES

//  Table 2:191 - Definition of TPMT_PUBLIC Structure
typedef struct tpmt_public
{
    TPMI_ALG_PUBLIC type;  //查看TCG_TPM2_Part1 27.2.2 : type . The allowed values for type are: TPM_ALG_SYMCIPHER, TPM_ALG_KEYEDHASH, TPM_ALG_RSA, or TPM_ALG_ECC.
    TPMI_ALG_HASH nameAlg; //查看TCG_TPM2_Part1 27.2.3 : nameAlg .
    // 查看TCG_TPM2_Part2  8.3  TPMA_OBJECT (Object Attributes)
    // This contains the set of attributes of the object. These attributes are in five classes:
    // 1)  usage (sign, encrypt, restricted);
    // 2)  authorization (userWithAuth, adminWithPolicy, noDA);
    // 3)  duplication (fixedParent, fixedTPM, encryptedDuplication);
    // 4)  creation (sensitiveDataOrigin); and
    // 5)  persistence (stClear).
    TPMA_OBJECT objectAttributes;
    TPM2B_DIGEST authPolicy; //查看TCG_TPM2_Part1 27.2.5 : authPolicy . If use of an object is to be gated by a policy (including PCR), the template will contain the policy hash. Otherwise, this entry will be set to the Empty Policy.

    // 查看TCG_TPM2_Part1 27.2.6 : parameters .
    //This field contains parameters that describe the details of the object indicated in type.
    //For a Storage Key that has fixedParent SET in its objectAttributes, these parameters will be identical to the parameters of the Storage Parent. For other objects, these parameters may vary according to the type and application.
    TPMU_PUBLIC_PARMS parameters;

    // 查看TCG_TPM2_Part1 27.2.7 : unique .
    // The unique field of the template is the only field in the public area that is replaced by the TPM during the object creation process. The caller may place any value in this field as long as the structure of the value is consistent with the type field. That is, this field should be structured in the same way as the data that will be placed in this field by the TPM. The caller may also set the size of this field to zero and the TPM will replace it with a correctly sized structure.
    // 模板的唯一字段是公共区域的唯一字段，在对象创建过程中被TPM替换。只要值的结构与类型字段一致，调用者可以在这个字段中放置任何值。也就是说，这个字段的结构应该与TPM将放在这个字段中的数据相同。调用者也可以将这个字段的大小设置为零，TPM将用一个正确大小的结构替换它。
    // 创建参数 参考 TCG_TPM2_Part1 27.5.3 : unique .
    TPMU_PUBLIC_ID unique;
} __attribute__((packed)) RECORD(TPM2_PUBLIC, TPMT_PUBLIC);
typedef RECORD(TPM2_PUBLIC, TPMT_PUBLIC) TPMT_PUBLIC; //查看TCG_TPM2_Part1 27.2 Public Area Template

// Table 2:192 - Definition of TPM2B_PUBLIC Structure
typedef struct tpm2b_public
{
    UINT16 size;
    TPMT_PUBLIC publicArea; // publicArea:the public area ;type :+TPMT_PUBLIC .the public area // NOTE:  The “+” indicates that the caller may specify that use  of TPM_ALG_NULL is allowed for nameAlg.
} __attribute__((packed)) RECORD(TPM2_AUTH, TPM2B_PUBLIC);
typedef RECORD(TPM2_AUTH, TPM2B_PUBLIC) TPM2B_PUBLIC;

// Table 2:193 - Definition of TPM2B_TEMPLATE Structure
typedef struct tpm2b_template
{
    TPM2B b;
} __attribute__((packed)) TPM2B_TEMPLATE;
// Table 2:194 - Definition of TPM2B_PRIVATE_VENDOR_SPECIFIC Structure
typedef struct tpm2b_private_vendor_sprcific
{
    TPM2B b;
} __attribute__((packed)) TPM2B_PRIVATE_VENDOR_SPECIFIC;

// Table 2:195 - Definition of TPMU_SENSITIVE_COMPOSITE Union
typedef struct tpmu_sensitive_composite
{
#if ALG_ECC
    TPM2B_ECC_PARAMETER ecc;
#endif // ALG_ECC
#if ALG_KEYEDHASH
    TPM2B_SENSITIVE_DATA bits;
#endif // ALG_KEYEDHASH
#if ALG_SYMCIPHER
    TPM2B_SYM_KEY sym;
#endif // ALG_SYMCIPHER
    TPM2B_PRIVATE_VENDOR_SPECIFIC any;
} __attribute__((packed)) TPMU_SENSITIVE_COMPOSITE;

//  Table 2:196 - Definition of TPMT_SENSITIVE Structure
typedef struct tpmt_sensitive
{
    TPMI_ALG_PUBLIC sensitiveType;
    TPM2B_AUTH authValue;
    TPM2B_DIGEST seedValue;
    TPMU_SENSITIVE_COMPOSITE sensitive;
} __attribute__((packed)) TPMT_SENSITIVE;

/* Table 204 - Definition of TPM2B_ID_OBJECT Structure <IN/OUT> */
typedef struct tpm2b_id_object
{
    TPM2B b;
} __attribute__((packed)) TPM2B_ID_OBJECT;
#define TYPE_OF_TPMA_NV UINT32
#define TPMA_NV_TO_UINT32(a) (*((UINT32 *)&(a)))
#define UINT32_TO_TPMA_NV(a) (*((TPMA_NV *)&(a)))
#define TPMA_NV_TO_BYTE_ARRAY(i, a) \
    UINT32_TO_BYTE_ARRAY((TPMA_NV_TO_UINT32(i)), (a))
#define BYTE_ARRAY_TO_TPMA_NV(i, a)         \
    {                                       \
        UINT32 x = BYTE_ARRAY_TO_UINT32(a); \
        i = UINT32_TO_TPMA_NV(x);           \
    }
typedef struct TPMA_NV
{ // Table 2:208
    unsigned PPWRITE : 1;
    unsigned OWNERWRITE : 1;
    unsigned AUTHWRITE : 1;
    unsigned POLICYWRITE : 1;
    unsigned TPM_NT : 4;
    unsigned Reserved_bits_at_8 : 2;
    unsigned POLICY_DELETE : 1;
    unsigned WRITELOCKED : 1;
    unsigned WRITEALL : 1;
    unsigned WRITEDEFINE : 1;
    unsigned WRITE_STCLEAR : 1;
    unsigned GLOBALLOCK : 1;
    unsigned PPREAD : 1;
    unsigned OWNERREAD : 1;
    unsigned AUTHREAD : 1;
    unsigned POLICYREAD : 1;
    unsigned Reserved_bits_at_20 : 5;
    unsigned NO_DA : 1;
    unsigned ORDERLY : 1;
    unsigned CLEAR_STCLEAR : 1;
    unsigned READLOCKED : 1;
    unsigned WRITTEN : 1;
    unsigned PLATFORMCREATE : 1;
    unsigned READ_STCLEAR : 1;
} TPMA_NV;
// This is the initializer for a TPMA_NV structure
#define TPMA_NV_INITIALIZER(                                  \
    ppwrite, ownerwrite, authwrite, policywrite,              \
    tpm_nt, bits_at_8, policy_delete, writelocked,            \
    writeall, writedefine, write_stclear, globallock,         \
    ppread, ownerread, authread, policyread,                  \
    bits_at_20, no_da, orderly, clear_stclear,                \
    readlocked, written, platformcreate, read_stclear)        \
    {                                                         \
        ppwrite, ownerwrite, authwrite, policywrite,          \
            tpm_nt, bits_at_8, policy_delete, writelocked,    \
            writeall, writedefine, write_stclear, globallock, \
            ppread, ownerread, authread, policyread,          \
            bits_at_20, no_da, orderly, clear_stclear,        \
            readlocked, written, platformcreate, read_stclear \
    }
/* Table 2:209 - Definition of TPMS_NV_PUBLIC Structure  */
typedef struct
{
    TPMI_RH_NV_INDEX nvIndex;
    TPMI_ALG_HASH nameAlg;
    TPMA_NV attributes;
    TPM2B_DIGEST authPolicy;
    UINT16 dataSize;
} __attribute__((packed)) TPMS_NV_PUBLIC;
/* Table 2:207 - Definition of TPM2B_NV_PUBLIC Structure  */
typedef struct
{
    UINT16 size;
    TPMS_NV_PUBLIC nvPublic;
} __attribute__((packed)) TPM2B_NV_PUBLIC;
/* Table 2:210 - Definition of TPM2B_CONTEXT_DATA Structure  */
typedef struct tpm2b_comtext_data
{
    TPM2B b;
} __attribute__((packed)) TPM2B_CONTEXT_DATA;
/* Table 2:211 - Definition of TPMS_CONTEXT Structure  */
typedef struct tpms_context
{
    UINT64 sequence;
    TPMI_DH_SAVED savedHandle;
    TPMI_RH_HIERARCHY hierarchy;
    TPM2B_CONTEXT_DATA contextBlob;
} __attribute__((packed)) TPMS_CONTEXT;

/* Table 2:213 - Definition of TPMS_CREATION_DATA Structure  */
typedef struct tpms_creation_data
{
    TPML_PCR_SELECTION pcrSelect;
    TPM2B_DIGEST pcrDigest;
    //TODO  NOTE： tpma_locality 和 TPMA_LOCALITY 定义在不同文件中，TPMA_LOCALITY为源码中定义； tpma_locality为自定义，直接使用枚举enum tpma_locality 的值。
    TPMA_LOCALITY locality;
    //TODO  NOTE： tpm_alg_id 和 TPM_ALG_ID 定义在不同文件中，TPM_ALG_ID 为源码中定义； tpm_alg_id 为自定义，直接使用枚举enum tpm_alg_id 的值。
    TPM_ALG_ID parentNameAlg;
    TPM2B_NAME parentName;
    TPM2B_NAME parentQualifiedName;
    TPM2B_DATA outsideInfo;
} __attribute__((packed)) RECORD(TPM2_AUTH, TPMS_CREATION_DATA);
typedef RECORD(TPM2_AUTH, TPMS_CREATION_DATA) TPMS_CREATION_DATA;

// Table 2:214 - Definition of TPM2B_CREATION_DATA Structure
typedef struct tpm2b_creation_data
{
    UINT16 size;
    TPMS_CREATION_DATA creationData;
} __attribute__((packed)) RECORD(TPM2_AUTH, TPM2B_CREATION_DATA);
typedef RECORD(TPM2_AUTH, TPM2B_CREATION_DATA) TPM2B_CREATION_DATA;
// Table 2:220 - Definition of TPM_AT Constants
typedef UINT32 TPM_AT;
#define TYPE_OF_TPM_AT UINT32
#define TPM_AT_ANY (TPM_AT)(0x00000000)
#define TPM_AT_ERROR (TPM_AT)(0x00000001)
#define TPM_AT_PV1 (TPM_AT)(0x00000002)
#define TPM_AT_VEND (TPM_AT)(0x80000000)

// Table 2:221 - Definition of TPM_AE Constants
typedef UINT32 TPM_AE;
#define TYPE_OF_TPM_AE UINT32
#define TPM_AE_NONE (TPM_AE)(0x00000000)

typedef struct
{ // Table 2:222
    TPM_AT tag;
    UINT32 data;
} TPMS_AC_OUTPUT;

/* Table 2:218 - Definition of TPML_AC_CAPABILITIES Structure  */
typedef struct
{
    UINT32 count;
    TPMS_AC_OUTPUT acCapabilities[MAX_AC_CAPABILITIES];
} TPML_AC_CAPABILITIES;

/* CryptHash.h */
#define tpmHashStateSHA1_t tpm_sha1_ctx_t
// #define tpmHashStateSHA1_t        SHA_CTX
#define tpmHashStateSHA256_t SHA256_CTX
#define tpmHashStateSHA384_t SHA512_CTX
#define tpmHashStateSHA512_t SHA512_CTX
#define tpmHashStateSM3_256_t SM3_context
typedef union
{
#if ALG_SHA1
    tpmHashStateSHA1_t Sha1;
#endif
#if ALG_SHA256
    tpmHashStateSHA256_t Sha256;
#endif
#if ALG_SHA384
    tpmHashStateSHA384_t Sha384;
#endif
#if ALG_SHA512
    tpmHashStateSHA512_t Sha512;
#endif
#if ALG_SM3_256
    tpmHashStateSM3_256_t Sm3_256;
#endif
    // Additions for symmetric block cipher MAC
#if SMAC_IMPLEMENTED
    SMAC_STATE smac;
#endif
    // to force structure alignment to be no worse than HASH_ALIGNMENT
#if HASH_ALIGNMENT == 4
    uint32_t align;
#else
    UINT64 align;
#endif
} ANY_HASH_STATE;
typedef ANY_HASH_STATE *PANY_HASH_STATE;
typedef const ANY_HASH_STATE *PCANY_HASH_STATE;

#define SM3_256_OID(NAME) MAKE_OID(NAME##SM3_256)
#define OID_PKCS1_SM3_256_VALUE 0x06, 0x08, 0x2A, 0x81, 0x1C, 0xCF, 0x55, \
                                0x01, 0x83, 0x78
SM3_256_OID(_PKCS1_); // 1.2.156.10197.1.504

//  When the TPM implements RSA, the hash-dependent OID pointers are part of the HASH_DEF. These
//    macros conditionally add the OID reference to the HASH_DEF and the HASH_DEF_TEMPLATE.
#define PKCS1_HASH_REF const BYTE *PKCS1;
#define PKCS1_OID(NAME) , OID_PKCS1_##NAME
// When the TPM implements ECC, the hash-dependent OID pointers are part of the HASH_DEF. These
//    macros conditionally add the OID reference to the HASH_DEF and the HASH_DEF_TEMPLATE.
#define ECDSA_HASH_REF const BYTE *ECDSA;
#define ECDSA_OID(NAME) , OID_ECDSA_##NAME
//  Define the prototypical function call for each of the methods. This defines the order in which
//    the parameters are passed to the underlying function.
#ifndef HASH_START_METHOD_DEF
#define HASH_START_METHOD_DEF void(HASH_START_METHOD)(void)
#endif
#ifndef HASH_DATA_METHOD_DEF
#define HASH_DATA_METHOD_DEF void(HASH_DATA_METHOD)(void)
#endif
#ifndef HASH_END_METHOD_DEF
#define HASH_END_METHOD_DEF void(HASH_END_METHOD)(void)
#endif
#ifndef HASH_STATE_COPY_METHOD_DEF
#define HASH_STATE_COPY_METHOD_DEF void(HASH_STATE_COPY_METHOD)(void)
#endif
#ifndef HASH_STATE_EXPORT_METHOD_DEF
#define HASH_STATE_EXPORT_METHOD_DEF void(HASH_STATE_EXPORT_METHOD)(void)
#endif
#ifndef HASH_STATE_IMPORT_METHOD_DEF
#define HASH_STATE_IMPORT_METHOD_DEF void(HASH_STATE_IMPORT_METHOD)(void)
#endif
typedef HASH_START_METHOD_DEF;
typedef HASH_DATA_METHOD_DEF;
typedef HASH_END_METHOD_DEF;
typedef HASH_STATE_COPY_METHOD_DEF;
typedef HASH_STATE_EXPORT_METHOD_DEF;
typedef HASH_STATE_IMPORT_METHOD_DEF;
typedef struct _HASH_METHODS
{
    HASH_START_METHOD *start;
    HASH_DATA_METHOD *data;
    HASH_END_METHOD *end;
    HASH_STATE_COPY_METHOD *copy;      // Copy a hash block
    HASH_STATE_EXPORT_METHOD *copyOut; // Copy a hash block from a hash
    // context
    HASH_STATE_IMPORT_METHOD *copyIn; // Copy a hash block to a proper hash
    // context
} HASH_METHODS, *PHASH_METHODS;

typedef const struct
{
    HASH_METHODS method;
    UINT16 blockSize;
    UINT16 digestSize;
    UINT16 contextSize;
    UINT16 hashAlg;
    const BYTE *OID;
    PKCS1_HASH_REF     // PKCS1 OID
        ECDSA_HASH_REF // ECDSA OID
} HASH_DEF, *PHASH_DEF;

//  TpmToOsslHash.h
#define HASH_START_METHOD_DEF void(HASH_START_METHOD)(PANY_HASH_STATE state)
#define HASH_START(hashState) \
    ((hashState)->def->method.start)(&(hashState)->state);
/* Add data to the hash */
#define HASH_DATA_METHOD_DEF                      \
    void(HASH_DATA_METHOD)(PANY_HASH_STATE state, \
                           PCBYTE buffer,         \
                           size_t size)
#define HASH_DATA(hashState, dInSize, dIn) \
    ((hashState)->def->method.data)(&(hashState)->state, dIn, dInSize)
/* Finalize the hash and get the digest */
#define HASH_END_METHOD_DEF \
    void(HASH_END_METHOD)(BYTE * buffer, PANY_HASH_STATE state)
#define HASH_END(hashState, buffer) \
    ((hashState)->def->method.end)(buffer, &(hashState)->state)
/* Copy the hash context */
/* NOTE: For import, export, and copy, memcpy() is used since there is no reformatting necessary
   between the internal and external forms. */
#define HASH_STATE_COPY_METHOD_DEF                      \
    void(HASH_STATE_COPY_METHOD)(PANY_HASH_STATE to,    \
                                 PCANY_HASH_STATE from, \
                                 size_t size)
#define HASH_STATE_COPY(hashStateOut, hashStateIn)            \
    ((hashStateIn)->def->method.copy)(&(hashStateOut)->state, \
                                      &(hashStateIn)->state,  \
                                      (hashStateIn)->def->contextSize)
/* Copy (with reformatting when necessary) an internal hash structure to an external blob */
#define HASH_STATE_EXPORT_METHOD_DEF                      \
    void(HASH_STATE_EXPORT_METHOD)(BYTE * to,             \
                                   PCANY_HASH_STATE from, \
                                   size_t size)
#define HASH_STATE_EXPORT(to, hashStateFrom)                                               \
    ((hashStateFrom)->def->method.copyOut)(&(((BYTE *)(to))[offsetof(HASH_STATE, state)]), \
                                           &(hashStateFrom)->state,                        \
                                           (hashStateFrom)->def->contextSize)
/* Copy from an external blob to an internal formate (with reformatting when necessary */
#define HASH_STATE_IMPORT_METHOD_DEF                   \
    void(HASH_STATE_IMPORT_METHOD)(PANY_HASH_STATE to, \
                                   const BYTE *from,   \
                                   size_t size)
#define HASH_STATE_IMPORT(hashStateTo, from)                                                    \
    ((hashStateTo)->def->method.copyIn)(&(hashStateTo)->state,                                  \
                                        &(((const BYTE *)(from))[offsetof(HASH_STATE, state)]), \
                                        (hashStateTo)->def->contextSize)
/* Function aliases. The code in CryptHash.c uses the internal designation for the functions. These
   need to be translated to the function names of the library. */
// #define tpmHashStart_SHA1           SHA1_Init   // external name of the initialization method
#define tpmHashData_SHA1 SHA1_Update
#define tpmHashEnd_SHA1 SHA1_Final
#define tpmHashStateCopy_SHA1 memcpy
#define tpmHashStateExport_SHA1 memcpy
#define tpmHashStateImport_SHA1 memcpy
#define tpmHashStart_SHA256 SHA256_Init
#define tpmHashData_SHA256 SHA256_Update
#define tpmHashEnd_SHA256 SHA256_Final
#define tpmHashStateCopy_SHA256 memcpy
#define tpmHashStateExport_SHA256 memcpy
#define tpmHashStateImport_SHA256 memcpy
#define tpmHashStart_SHA384 SHA384_Init
#define tpmHashData_SHA384 SHA384_Update
#define tpmHashEnd_SHA384 SHA384_Final
#define tpmHashStateCopy_SHA384 memcpy
#define tpmHashStateExport_SHA384 memcpy
#define tpmHashStateImport_SHA384 memcpy
#define tpmHashStart_SHA512 SHA512_Init
#define tpmHashData_SHA512 SHA512_Update
#define tpmHashEnd_SHA512 SHA512_Final
#define tpmHashStateCopy_SHA512 memcpy
#define tpmHashStateExport_SHA512 memcpy
#define tpmHashStateImport_SHA512 memcpy
#define tpmHashStart_SM3_256 sm3_starts_ext
#define tpmHashData_SM3_256 sm3_update_ext
#define tpmHashEnd_SM3_256 sm3_finish_ext
#define tpmHashStateCopy_SM3_256 memcpy
#define tpmHashStateExport_SM3_256 memcpy
#define tpmHashStateImport_SM3_256 memcpy
//  TpmToOsslHash.h
#define HASH_DEF_TEMPLATE(HASH, Hash)                               \
    HASH_DEF Hash##_Def = {                                         \
        {                                                           \
            (HASH_START_METHOD *)&tpmHashStart_##HASH,              \
            (HASH_DATA_METHOD *)&tpmHashData_##HASH,                \
            (HASH_END_METHOD *)&tpmHashEnd_##HASH,                  \
            (HASH_STATE_COPY_METHOD *)&tpmHashStateCopy_##HASH,     \
            (HASH_STATE_EXPORT_METHOD *)&tpmHashStateExport_##HASH, \
            (HASH_STATE_IMPORT_METHOD *)&tpmHashStateImport_##HASH, \
        },                                                          \
        HASH##_BLOCK_SIZE,  /*block size */                         \
        HASH##_DIGEST_SIZE, /*data size */                          \
        sizeof(tpmHashState##HASH##_t),                             \
        TPM_ALG_##HASH,                                             \
        OID_##HASH                                                  \
            PKCS1_OID(HASH) ECDSA_OID(HASH)};

/* These definitions are for the types that can be in a hash state structure. These types are used
   in the cryptographic utilities. This is a define rather than an enum so that the size of this
   field can be explicit. */
typedef BYTE HASH_STATE_TYPE;
#define HASH_STATE_EMPTY ((HASH_STATE_TYPE)0)
#define HASH_STATE_HASH ((HASH_STATE_TYPE)1)
#define HASH_STATE_HMAC ((HASH_STATE_TYPE)2)
#if CC_MAC || CC_MAC_Start
#define HASH_STATE_SMAC ((HASH_STATE_TYPE)3)
#endif
/* This is the structure that is used for passing a context into the hashing functions. It should be
   the same size as the function context used within the hashing functions. This is checked when the
   hash function is initialized. This version uses a new layout for the contexts and a different
   definition. The state buffer is an array of HASH_UNIT values so that a decent compiler will put
   the structure on a HASH_UNIT boundary. If the structure is not properly aligned, the code that
   manipulates the structure will copy to a properly aligned structure before it is used and copy
   the result back. This just makes things slower. */
/*     NOTE: This version of the state had the pointer to the update method in the state. This is to
       allow the SMAC functions to use the same structure without having to replicate the entire
       HASH_DEF structure. */
typedef struct _HASH_STATE
{
    HASH_STATE_TYPE type; // type of the context
    TPM_ALG_ID hashAlg;
    PHASH_DEF def;
    ANY_HASH_STATE state;
} HASH_STATE, *PHASH_STATE;
typedef const HASH_STATE *PCHASH_STATE;

/* An HMAC_STATE structure contains an opaque HMAC stack state. A caller would use this structure
   when performing incremental HMAC operations. This structure contains a hash state and an HMAC key
   and allows slightly better stack optimization than adding an HMAC key to each hash state. */
typedef struct hmacState
{
    HASH_STATE hashState;     // the hash state
    TPM2B_HASH_BLOCK hmacKey; // the HMAC key
} HMAC_STATE, *PHMAC_STATE;
/* This is for the external hash state. This implementation assumes that the size of the exported
   hash state is no larger than the internal hash state. */
typedef struct
{
    BYTE buffer[sizeof(HASH_STATE)];
} EXPORT_HASH_STATE, *PEXPORT_HASH_STATE;
typedef const EXPORT_HASH_STATE *PCEXPORT_HASH_STATE;

/*
 * Because array size can't be a const in C, the following two are macros.
 * Both sizes are in bytes.
 */
#define AES_MAXNR 14
#define AES_BLOCK_SIZE 16
/* This should be a hidden type, but EVP requires that the size be known */
struct aes_key_st
{
#ifdef AES_LONG
    unsigned long rd_key[4 * (AES_MAXNR + 1)];
#else
    unsigned int rd_key[4 * (AES_MAXNR + 1)];
#endif
    int rounds;
};
typedef struct aes_key_st AES_KEY;

#define tpmKeyScheduleAES AES_KEY
// /* CryptHash.h */

// /* 10.1.2 CryptEcc.h */
// #define CURVE_NAME(a) , a
// #define CURVE_NAME_DEF const char *name;
// typedef struct ECC_CURVE
// {
//     const TPM_ECC_CURVE          curveId;
//     const UINT16                 keySizeBits;
//     const TPMT_KDF_SCHEME        kdf;
//     const TPMT_ECC_SCHEME        sign;
//     const ECC_CURVE_DATA        *curveData; // the address of the curve data
//     const BYTE                  *OID;
//     CURVE_NAME_DEF
// } ECC_CURVE;
// extern const ECC_CURVE eccCurves[ECC_CURVE_COUNT];

// const ECC_CURVE ECC_CURVE_SM2_P256 = {TPM_ECC_SM2_P256, 256,  {ALG_KDF1_SP800_56A_VALUE, {{ALG_SM3_256_VALUE}}}, {TPM_ALG_SM2, {{TPM_ALG_SM2}}}, &SM2_P256, OID_ECC_SM2_P256 CURVE_NAME("SM2_P256")};

// /* CryptEcc.h */

#endif
